console.log(`
【fs 模块概述】
    Node.js 的文件系统模块 (fs) 允许我们与文件系统进行交互，
    提供了大量用于文件和目录操作的方法。这些方法通常有同步和异步两种版本。
  `);

console.log(`
【文件写入Api】
    1. fs.watchFile()             异步写入
    2. fs.writeFileSync()         同步写入
    3. fs.createWriteStream()     流式写入
    4. fs.appendFile()            异步追加写入
    5. fs.appendFileSync()        同步追加写入
`);
console.log(
  `使用文件写入Api前，需要先导入fs模块：
   导入模块、require 是 Node.js 环境中的'全局'变量，用来导入模块
   const fs = require("fs");
  `
);
const fs = require("fs");
console.log(`
【异步写入】fs.writeFile():
        功能：
            异步写入文件，如果文件不存在则创建，如果文件存在则覆盖文件内容
        语法：
            fs.writeFile(path, data[, options], callback)
        参数：
            path 要写入的文件路径
            data 要写入的内容
            options 写入配置项
            callback 写入完成后的回调函数
                 err 错误对象  
                 written 写入的字节数
                 buffer 写入的内容
  `);
const writeFileUrl = "./fs.writeFile()异步写入.txt";
const writeFileText = "天行健、君子以自强不息、地势坤、君子以厚德载物\n";
const writeFileOptions = { flag: "a+", encoding: "utf-8" };
fs.writeFile(writeFileUrl, writeFileText, writeFileOptions, (err) => {
  if (err) {
    console.log(err);
    return;
  }
  console.log("fs.writeFile()：写入成功");
});

console.log(`
【同步写入】fs.writeFileSync():
        功能：
            同步写入文件，如果文件不存在则创建，如果文件存在则覆盖文件内容
        语法：
            fs.writeFileSync(path, data[, options])
        参数：
            path 要写入的文件路径
            options 写入配置项
            data 要写入的内容
`);
const writeFileSyncUrl = "./fs.writeFileSync(同步写入.txt";
const writeFileSyncText = "天行健、君子以自强不息、地势坤、君子以厚德载物\n";
const writeFileSyncOptions = { flag: "a+", encoding: "utf-8" };
try {
  fs.writeFileSync(writeFileSyncUrl, writeFileSyncText, writeFileSyncOptions);
  console.log("fs.writeFileSync()：写入成功");
} catch (e) {
  console.log(e);
}

console.log(`
【流式写入】fs.createWriteStream():
        功能：
            流式写入文件，将文件分成多个块，每个块写入一次
        语法：
            fs.createWriteStream(path[, options])
        参数：
            path 要写入的文件路径
            options 写入配置项
        特点：
            1. 流式写入是异步的，不会阻塞后续代码的执行
            2. 流式写入如果文件不存在会自动创建文件
            3. 流式写入如果文件存在会覆盖文件内容
            4. 流式写入可以多次写入
            5. 流式写入需要手动结束
`);
const writeStreamUrl = "./fs.createWriteStream()流式写入.txt";
const writeStreamOptions = { flag: "a+", encoding: "utf-8" };
const writeStreamText = "天行健、君子以自强不息、地势坤、君子以厚德载物\n";
const ws = fs.createWriteStream(writeStreamUrl, writeStreamOptions);
ws.write(writeStreamText);
ws.write(writeStreamText);
ws.end();
ws.on("finish", () => {
  console.log("流式写入完成");
});

console.log(`
【追加写入】fs.appendFile():
        功能：
            异步追加写入文件，如果文件不存在则创建，如果文件存在则追加写入文件内容
        语法：
            fs.appendFile(path, data[, options], callback)
        参数：
            path 要写入的文件路径
            data 要写入的内容
            options 写入配置项
            callback 写入完成后的回调函数
`);
const appendFileUrl = "./fs.appendFile()异步写入.txt";
const appendFileText = "天行健、君子以自强不息、地势坤、君子以厚德载物\n";
const appendFileOptions = { flag: "a+", encoding: "utf-8" };
fs.appendFile(appendFileUrl, appendFileText, appendFileOptions, (err) => {
  if (err) {
    console.log(err);
    return;
  }
  console.log("fs.appendFile()：写入成功");
});

console.log(`
【同步追加写入】fs.appendFileSync():
        功能：
            同步追加写入文件，如果文件不存在则创建，如果文件存在则追加写入文件内容
        语法：
            fs.appendFileSync(path, data[, options])
        参数：
            path 要写入的文件路径
            data 要写入的内容
            options 写入配置项
`);
const appendFileSyncUrl = "./fs.appendFileSync()异步写入.txt";
const appendFileSyncText = "天行健、君子以自强不息、地势坤、君子以厚德载物\n";
const appendFileSyncOptions = { flag: "a+", encoding: "utf-8" };
try {
  fs.appendFileSync(
    appendFileSyncUrl,
    appendFileSyncText,
    appendFileSyncOptions
  );
  console.log("fs.appendFileSync()：写入成功");
} catch (e) {
  console.log(e);
}

console.log(`
【Promise写入】fs.promises.writeFile():
        功能：
            Promise方式写入文件
        语法：
            fs.promises.writeFile(path, data[, options])
        参数：
            path 要写入的文件路径
            data 要写入的内容
            options 写入配置项
`);
const PromiseWriteFileUrl = "./promises异步写入.txt";
const PromiseWriteFileText = "天行健、君子以自强不息、地势坤、君子以厚德载物\n";
const PromiseWriteFileOptions = { flag: "a+", encoding: "utf-8" };
fs.promises
  .writeFile(PromiseWriteFileUrl, PromiseWriteFileText, PromiseWriteFileOptions)
  .then(() => {
    console.log("Promise写入成功");
  })
  .catch(() => {
    console.log("Promise写入失败");
  });

console.log(`
【options配置项详解】
    功能：
        配置文件写入的选项
    参数：
        1. flag 写入方式：
          - a+ 表示追加写入、如果文件不存在则创建文件
          - w 表示写入、如果文件不存在则创建文件、如果文件存在则覆盖文件内容
          - w+ 表示写入并读取、如果文件不存在则创建文件、如果文件存在则覆盖文件内容
          - a 表示追加写入、如果文件不存在则创建文件
          - r 表示读取、如果文件不存在则报错
          - r+ 表示读取并写入、如果文件不存在则报错
        2. encoding 字符编码
          - utf8 编码
          - base64 编码
          - binary 二进制编码
          - null 无编码
          - base64url 编码
          - ascii 7位编码
          - utf16le 16位小端编码
          - ucs2 16位编码
          - base64 编码
        3. mode 文件权限:
          - 0o666 读写权限
          - 0o644 只读权限
          - 0o755 读写执行权限
          - 0o744 只读执行权限
          - 0o733 读写执行权限
          - 0o722 读写执行权限
          - 0o711 读写执行权限
          - 0o700 只读执行权限
        4. fd 文件描述符:
          - 0 标准输入
          - 1 标准输出
          - 2 标准错误
        5. start 开始写入的位置
        6. end 结束写入的位置
        7. highWaterMark 每次写入的字节数
        8. pos 写入的位置、从文件的第几个字节开始写入
        9. atomic 原子写入
        10. signal 信号量、信号量是一个计数器，用于控制对共享资源的访问。
  `);

console.log(`
【常见问题与解决方案】
        1. 路径问题：
          - 使用相对路径时要注意当前工作目录
          - 建议使用绝对路径或__dirname组合路径，避免路径错误
          - 示例：const filePath = path.join(__dirname, 'file.txt');

        2. 错误处理：
          - 异步方法：使用回调函数的err参数或Promise的catch方法
          - 同步方法：必须使用try-catch捕获异常
          - 流式方法：监听'error'事件

        3. 性能优化：
          - 小文件（<100MB）：可以使用writeFile或appendFile
          - 大文件（>100MB）：强烈建议使用createWriteStream
          - 频繁写入：考虑合并写入请求或使用缓存

        4. 原文件中的语法错误：
          - writeFileSyncUrl变量定义中的路径字符串末尾缺少右引号")"
          - 修正：const writeFileSyncUrl = "./fs.writeFileSync(同步写入).txt";

        5. 代码优化建议：
          - 使用path模块处理文件路径，避免硬编码路径
          - 对于频繁的文件操作，考虑使用连接池或缓存
          - 在生产环境中，确保有完善的错误处理和日志记录
    `);

console.log(`
【常见问题与解决方案】
        1. 配置文件读写：使用writeFile/readFile
        2. 日志记录：使用appendFile或createWriteStream
        3. 大文件处理：必须使用createWriteStream
        4. 初始化操作：可以使用writeFileSync
        5. 现代异步开发：使用fs.promises API结合async/await
    `);

console.log(`
【文件写入方法比较】
        1. writeFile：异步写入，简单易用，适用于小文件。
        2. appendFile：异步追加写入，适用于日志记录。
        3. createWriteStream：流式写入，适用于大文件，支持暂停和恢复。
        4. writeFileSync：同步写入，适用于初始化操作。
        5. fs.promises.writeFile：Promise方式写入，适用于现代异步开发。
  `);
